/* File:       network_setup.c
* Function:    supply the network setup moudle function
* Creator:     LDM
* Data:        2009.05.07
* status:      create
* History:
*/

/******************************************************************************
*****************************head file included area***************************
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include <libintl.h>
#include <locale.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <arpa/inet.h>

#include "lan.h"

/******************************************************************************
****************************macro definition area******************************
******************************************************************************/
#define DEBUG 1
#ifdef DEBUG
#define DBG(txt, args... ) fprintf(stderr, "DIAL_UP-DEBUG: " txt , ##args )
#else
#define DBG(txt, args... ) /* nothing */
#endif

#define _(text) gettext(text)
#define __(text) gettext(text)

#define LOCAL_PIDF              "/var/run/dhclient.pid_"
#define STATUS_FILE             "/etc/network/lan.status"
#define NET_CONFIG_FOLDER       "/etc/network/"

static gboolean RUNNING;
static gboolean DYNAMIC_CONNECT_RUN;

/******************************************************************************
***************************structure definition area***************************
******************************************************************************/
typedef enum
{
    RESPONSE_DHCP = 1,
    RESPONSE_STATIC
}Response;

/******************************************************************************
***************************static func declare area****************************
******************************************************************************/
static void wirte_interface_info(Iface_t *iface);

/******************************************************************************
*******************************Func realize eara******************************
******************************************************************************/

/****************** static func realize eara ******************/
static void NetprintNull(FILE *fp, char *format, ...)
{
    return;
}

static gint key_press_event(GtkWidget *widget, GdkEventButton *event, NetWorkLan *lan)
{
    GdkEventKey *key;
    
	if(RUNNING){
		return TRUE;
	}
    
    gtk_main_quit();
    return FALSE;
}

static gboolean dynamic_connect_style(NetWorkLan *lan)
{
    gchar *buffer;
    static count=0;
    GtkWidget *label = NULL;
    
    if(!DYNAMIC_CONNECT_RUN)
    {
        printf("%s return\n", __func__);
        return FALSE;
    }
    
    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __func__);
        return;
    }
    
	//active build-in wifi 
    label=gtk_object_get_data (GTK_OBJECT(lan->connect_window), "label");
    if(label){
        if(count%3==0){
            buffer=g_strdup_printf("%s%s",_("Connecting"),".  ");
        }else if(count%3==1){
            buffer=g_strdup_printf("%s%s",_("Connecting"),".. ");
        }else{
            buffer=g_strdup_printf("%s%s",_("Connecting"),"...");
        }
        gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER);
        gtk_label_set_line_wrap(GTK_LABEL(label),TRUE);        
        gtk_label_set_label(GTK_LABEL(label),buffer); 
    }
    count++;
    return TRUE;
}

static gboolean do_detect(NetWorkLan *lan)
	{
	GtkWidget *widget;
	gchar buffer[256];
	FILE *fd;
    int err_num;

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __FUNCTION__);
        return FALSE;
    }
    
	if(RUNNING){
		return TRUE;
	}

	fd=fopen(STATUS_FILE, "r");
	if (!fd)
    {
        printf("Error:lan.status file not found!\n");
        return FALSE;
    }
    
    fscanf(fd, "%d", &err_num);	
	printf("err_num=%d\n",err_num);
    fclose(fd);
    switch(err_num)
    {
    case 0:
        return TRUE;
        
    case 1:
        RUNNING = FALSE;
        sprintf(buffer,"%s",_("   Failed.   "));
        break;
        
    case 2:
        RUNNING = FALSE;
        sprintf(buffer,"%s",_("  Connected. "));
        break;
        
    case 3:
        RUNNING = FALSE;
        sprintf(buffer,"%s",_("  Time out. "));
        break;
        
    default:
        RUNNING = FALSE;
        sprintf(buffer,"%s",_("   Failed.   "));
        return FALSE;
    }	  
    widget=g_object_get_data(G_OBJECT(lan->connect_window),"label");
    if(widget){  
        gtk_label_set_justify(GTK_LABEL(widget),GTK_JUSTIFY_CENTER);
        gtk_label_set_line_wrap(GTK_LABEL(widget),TRUE);
        gtk_label_set_label(GTK_LABEL(widget),buffer);
    }	
    return FALSE;
}

static void sig_action (int signo)
{
    FILE *fd = NULL;
    
  	RUNNING=FALSE;
    DYNAMIC_CONNECT_RUN=FALSE;
}

static gboolean do_connect(NetWorkLan *lan)
{
    pid_t pid;  
    
    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __func__);
        return FALSE;
    }
    if (signal(SIGCHLD, sig_action) == SIG_ERR)
    {
        printf ("error in signal!\n");
    }
    
    pid=fork();
    if(pid<0)
    {
        printf("fork error\n");
    }
    else if(pid==0)
    {
        execl("/etc/init.d/Snetwork", "Snetwork", "restart", (char *)0);
    }
    return FALSE;
}

static void lan_connect(NetWorkLan *lan)
{
    GtkWidget *label;
    GtkWidget *vbox;
    GtkWidget *connect_window;

    // check param
    if (lan == NULL)
    {
        DBG("input param invalid in %s\n", __func__);
        return;
    }
    gtk_rc_parse_string( "style \"font-default\"" \
                         "{font_name=\"Sans 16\"}" \
                         "class \"*\" style \"font-default\"" );
    
    remove(STATUS_FILE);
    lan->connect_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);//GTK_WINDOW_POPUP
    gtk_window_set_type_hint(GTK_WINDOW(lan->connect_window), GDK_WINDOW_TYPE_HINT_DIALOG);
    gtk_window_set_decorated(GTK_WINDOW(lan->connect_window), FALSE);
    gtk_widget_add_events(GTK_WIDGET(lan->connect_window), GDK_KEY_PRESS_MASK);
    g_signal_connect(lan->connect_window, "key-press-event", G_CALLBACK(key_press_event), NULL);

    vbox = gtk_vbox_new(FALSE, 0);
    label = gtk_label_new(_("Connecting..."));
    g_object_set_data(G_OBJECT(lan->connect_window), "label", label);
    gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0);
    gtk_container_add(GTK_CONTAINER(lan->connect_window), vbox);
    gtk_window_set_position(GTK_WINDOW (lan->connect_window), GTK_WIN_POS_CENTER);
    gtk_widget_show_all(lan->connect_window);

    DYNAMIC_CONNECT_RUN=TRUE;
    g_timeout_add(1000,(GSourceFunc)dynamic_connect_style,lan);

    RUNNING=TRUE;
    g_idle_add((GSourceFunc)do_connect, lan);
    g_idle_add((GSourceFunc)do_detect, lan);
}

/*static void create_editable_entry (Iface_t *piface, GtkWidget *attach_to,
                    		       gchar *wprefix, gchar *ltext, gchar *wdata,
                    		       gchar *tooltip, gint clnr)*/
static void create_editable_entry(GtkWidget *attach_to,
                                   gchar *wprefix, gchar *ltext, gchar *wdata,
                                   gchar * tooltip, gint clnr, NetWorkLan *lan)
{
	GtkWidget *label;
    GtkWidget *entry;
	guint gpe_boxspacing = 5;

	label = gtk_label_new(ltext);
	gtk_tooltips_set_tip(lan->tooltips, label, tooltip, NULL);
	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
	gtk_table_attach(GTK_TABLE(attach_to), label, 0, 1, clnr, clnr + 1,
        			  (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_FILL),
        			  gpe_boxspacing, gpe_boxspacing);
    
	entry = gtk_entry_new();
	gtk_tooltips_set_tip(lan->tooltips, entry, tooltip, NULL);
    g_object_set_data(G_OBJECT(lan->static_window), wprefix, entry);
	gtk_entry_set_text(GTK_ENTRY(entry), wdata);
	gtk_entry_set_editable(GTK_ENTRY(entry), TRUE);
	gtk_table_attach(GTK_TABLE(attach_to), entry, 1, 3, clnr, clnr + 1,
    			  (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL),
    			  gpe_boxspacing, gpe_boxspacing);
}

static gint esc_key_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    GdkEventKey *key;
    
    key = (GdkEventKey *)event;
    if (key->keyval != GDK_Escape)
    {
        return FALSE;
    }
    
    gtk_main_quit();
    return TRUE;
}

static void show_message_box(GtkWidget *parent, gchar *message)
{
    GtkWidget *dialog;
    dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
                                    GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
                                    GTK_MESSAGE_INFO,
                                    GTK_BUTTONS_OK,
                                    message);
    gtk_widget_show_all(dialog);
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}

static gboolean address_is_valid(gchar *ip)
{
    struct sockaddr_in addr;

    if (ip == NULL)
    {
        return FALSE;
    }
    
    if (inet_pton(AF_INET, ip, &addr.sin_addr) == 0)
    {
        perror("inet_pton");
        printf("invalid: (%s), len: (%d)\n", ip, strlen(ip));
        return FALSE;
    }
    
    return TRUE;
}

static void save_nameserver(NetWorkLan *lan)
{
    gchar *name1 = NULL;
    gchar *name2 = NULL;
    gboolean changed = FALSE;
    GtkWidget *entry;
    gboolean invalid = FALSE;

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __func__);
        return;
    }
    
	// save nameserver
    FILE *fd = fopen("/etc/resolv.conf", "w");     
    if (!fd)
    {
        printf("file /etc/resolv.conf cann't access\n");
    }
#if 0
	entry = g_object_get_data(G_OBJECT(lan->static_window), "nameserver");
	if (entry)
	{
		name1 = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (strlen(name1) > 0)
        {
            if (address_is_valid(name1))
            {
                lan->iface.nameserver[0] = g_strdup(name1);
                fprintf(fd, "nameserver %s\n", name1);
            }
            else
            {
                show_message_box(lan->static_window, _("nameserver option invalid"));  
                fclose(fd);
                return;
            }
        }
        else
        {
            lan->iface.nameserver[0] = NULL;
        }
	}

	entry = g_object_get_data(G_OBJECT(lan->static_window), "nameserver2");
	if (entry)
	{
		name2 = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (strlen(name2)>0)
        {
            if (address_is_valid(name2))
            {
                lan->iface.nameserver[1] = g_strdup(name2);
                fprintf(fd, "nameserver %s\n", name2);
            }
            else
            {
                show_message_box(lan->static_window, _("nameserver option invalid"));        
                fclose(fd);
                return;
            }
        }
        else
        {
            lan->iface.nameserver[1] = NULL;
        }
	}
#endif
    if (lan->iface.nameserver[0])
    {
        fprintf(fd, "nameserver %s\n", lan->iface.nameserver[0]);
    }
    if (lan->iface.nameserver[1])
    {
        fprintf(fd, "nameserver %s\n", lan->iface.nameserver[1]);
    }
    fclose(fd);

    FILE *fd_bak = fopen("/etc/resolv.conf_bak", "w");        //add by zzw 2009.09.09
    if (!fd_bak)
    {
        printf("file /etc/resolv.conf cann't access\n");
    }	

    if (lan->iface.nameserver[0])
    {
        fprintf(fd_bak, "nameserver %s\n", lan->iface.nameserver[0]);
    }
    if (lan->iface.nameserver[1])
    {
        fprintf(fd_bak, "nameserver %s\n", lan->iface.nameserver[1]);
    }
    fclose(fd_bak);

    return;
}

static void set_staticip(GtkWidget* widget, NetWorkLan *lan)
{
		GtkWidget *entry;
    gchar *name1 = NULL;
    gchar *name2 = NULL;
		gchar *newval = NULL;
    gchar *ipinfo = NULL;

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __FUNCTION__);
        return;
    }
    
    if (lan->iface.nameserver[0] != NULL)
    {
        g_free(lan->iface.nameserver[0]);
        lan->iface.nameserver[0] = NULL;
    }
    if (lan->iface.nameserver[1] != NULL)
    {
        g_free(lan->iface.nameserver[1]);
        lan->iface.nameserver[1] = NULL;
    }

    //printf("before set static ip:\n");
    //printf("ip: %s, netmask: %s, gateway: %s, dns1: %s, dns2: %s\n", lan->iface.address, lan->iface.netmask,
    //   lan->iface.gateway, lan->iface.nameserver[0], lan->iface.nameserver[1]);
    entry = g_object_get_data(G_OBJECT(lan->static_window), "address");
    if (entry) 
    {
        newval = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (address_is_valid(newval))
        {
            strcpy(lan->iface.address, newval);
        }
        else
        {
            ipinfo=g_strdup(_("Input Address is invalid"));
            show_message_box(lan->static_window, ipinfo);
            return;
        }
    }

    entry = g_object_get_data(G_OBJECT(lan->static_window), "netmask");
    if (entry) 
    {
        newval = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (address_is_valid(newval))
        {
            strcpy(lan->iface.netmask, newval);
        }
        else
        {
            ipinfo=g_strdup(_("Input Netmask is invalid"));
            show_message_box(lan->static_window, ipinfo); 
            return;
        }
    }

    entry = g_object_get_data(G_OBJECT(lan->static_window), "gateway");
    if (entry)
    {
        newval = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (address_is_valid(newval))
        {
            strcpy(lan->iface.gateway, newval);
        }
        else
        {
            ipinfo=g_strdup(_("Input Gateway is invalid"));
            show_message_box(lan->static_window, ipinfo);
            return;
        }
    }
    
	entry = g_object_get_data(G_OBJECT(lan->static_window), "nameserver");
	if (entry)
	{
		name1 = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (strlen(name1) > 7)
        {
            if (address_is_valid(name1))
            {
                lan->iface.nameserver[0] = g_strdup(name1);
            }
            else
            {
                show_message_box(lan->static_window, _("nameserver option invalid"));  
                return;
            }
        }
	}

	entry = g_object_get_data(G_OBJECT(lan->static_window), "nameserver2");
	if (entry)
	{
		name2 = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
        if (strlen(name2)>7)
        {
            if (address_is_valid(name2))
            {
                lan->iface.nameserver[1] = g_strdup(name2);
            }
            else
            {
                printf("LAN::show nameserver option invalid 2: %s, len = %d\n", name2, strlen(name2));
                show_message_box(lan->static_window, _("nameserver option invalid"));        
                return;
            }
        }
	}
    save_nameserver(lan);
    wirte_interface_info(&(lan->iface));
    printf("write interface info: isdhcp: %d, ip: %s, netmask: %s, gateway: %s, nameserver1: %s, nameserver2: %s\n", 
            lan->iface.isdhcp, lan->iface.address, lan->iface.netmask, lan->iface.gateway, lan->iface.nameserver[0], lan->iface.nameserver[1]);
    do_connect(lan);
    if (lan->static_window)
    {
        gtk_widget_destroy(lan->static_window);
    }
    gtk_main_quit();
}

void get_name_server(const gchar *file, NetWorkLan *lan)
{
    gchar *content;
    gchar **lines;
    gint length;
    gchar *delim;
    gint i = 0;
    GError *err = NULL;

    // check param 
    if (NULL == lan)
    {
        return;
    }

    delim = g_strdup("\n");
    if (!g_file_get_contents(file, &content, &length, &err))
    {
        fprintf(stderr,"Could not access file: %s.\n",file);
        return;
    }
    lines = g_strsplit(content, delim, 2048);
    g_free(delim);
    delim = g_strdup("");
    g_free(content);
    
    gint k = 0;
    while (lines[i])
    {
        if ((g_strrstr(g_strchomp(lines[i]), "nameserver"))
            && (!g_str_has_prefix(g_strchomp(lines[i]), "#")))
        {
            delim = g_strrstr(lines[i],"=");
            if (delim)
                delim = g_strdup(g_strchomp(delim) + 1);
            if (!delim)
            {
                delim = g_strrstr(lines[i]," ");
                if (delim)
                delim = g_strdup(g_strchomp(delim) + 1);
            }
            lan->iface.nameserver[k++] = g_strdup(delim);
            if (k >= 2) return;
        }
        i++;
    }
	
  g_strfreev(lines);
}

static void set_focus_netmask(GtkEntry *widget, NetWorkLan *lan)
{
    GtkWidget *entry;
    printf("!!!!!!!!!!!%p\n" ,lan);

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __FUNCTION__);
        return;
    }
    
    entry = g_object_get_data(G_OBJECT(lan->static_window), "netmask");
    gtk_window_set_focus(GTK_WINDOW(lan->static_window), entry);
}

static void set_focus_gateway(GtkEntry *widget, NetWorkLan *lan)
{
    GtkWidget *entry;

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __FUNCTION__);
        return;
    }
    
    entry = g_object_get_data(G_OBJECT(lan->static_window), "gateway");
    gtk_window_set_focus(GTK_WINDOW(lan->static_window), entry);
}

static void set_focus_nameserver(GtkEntry *widget, NetWorkLan *lan)
{
    GtkWidget *entry;

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __FUNCTION__);
        return;
    }
    
    entry = g_object_get_data(G_OBJECT(lan->static_window), "nameserver");
    gtk_window_set_focus(GTK_WINDOW(lan->static_window), entry);
}

static void set_focus_nameserver2(GtkEntry *widget, NetWorkLan *lan)
{
    GtkWidget *entry;

    // check param
    if (NULL == lan)
    {
        DBG("input param invalid in %s\n", __FUNCTION__);
        return;
    }
    
    entry = g_object_get_data(G_OBJECT(lan->static_window), "nameserver2");
    gtk_window_set_focus(GTK_WINDOW(lan->static_window), entry);
}

gint delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)//add by zzw 2009.09.25
{	
	//printf("In delete event!\n");
	gtk_main_quit();
}

static void create_network_widgets(NetWorkLan *lan)//Iface_t iface
{
	GtkWidget *ctable;
    GtkWidget *entry;
	guint gpe_boxspacing = 15;
	guint gpe_border = 10;
	gchar *tmpval;
    gchar *nameserverfile = NULL;

    // check param
    if (NULL == lan)
    {
        fprintf(stderr, "input param invalid in %s\n", __func__);
        return;
    }
    lan->static_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width(GTK_CONTAINER(lan->static_window), 30);//10
    gtk_window_fullscreen(GTK_WINDOW(lan->static_window));
    gtk_widget_add_events(GTK_WIDGET(lan->static_window), GDK_KEY_PRESS_MASK);
    gtk_signal_connect(GTK_OBJECT(lan->static_window), "key-press-event",GTK_SIGNAL_FUNC(esc_key_press),NULL);
    gtk_signal_connect(GTK_OBJECT(lan->static_window), "delete_event",GTK_SIGNAL_FUNC(delete_event),NULL);

	ctable = gtk_table_new(16, 3, FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(ctable), gpe_boxspacing);
	gtk_table_set_row_spacings(GTK_TABLE(ctable), gpe_boxspacing);
    gtk_container_add(GTK_CONTAINER(lan->static_window), ctable);

	lan->tooltips = gtk_tooltips_new();
    create_editable_entry(ctable, "address", _("Address"), lan->iface.address,  
                            _("Enter your IP address here, e.g. 192.168.1.2"), 0, lan);  
    entry=g_object_get_data(G_OBJECT(lan->static_window), "address");
    printf("~~~~~~~~%p\n" ,lan);
    g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_focus_netmask), lan);
                     
    
    create_editable_entry (ctable, "netmask", _("Netmask"), lan->iface.netmask, 
                            _("Enter your netmask here, e.g. 255.255.255.0 in most cases"), 1, lan);
    entry=g_object_get_data(G_OBJECT(lan->static_window), "netmask");
    g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_focus_gateway), lan);
    
    
    create_editable_entry(ctable, "gateway", _("Gateway"), lan->iface.gateway,
                            _("Enter the IP Address of your default gateway here."), 2, lan);  
    entry=g_object_get_data(G_OBJECT(lan->static_window), "gateway");
    g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_focus_nameserver), lan);

	create_editable_entry(ctable, "nameserver", _("Primary DNS server"), lan->iface.nameserver[0],
				       _("Enter the Primary DNS(name-) server to use here."), 3, lan);
    entry=g_object_get_data(G_OBJECT(lan->static_window), "nameserver");
    g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_focus_nameserver2), lan);
    
    
	create_editable_entry(ctable, "nameserver2", _("Secondary DNS server"), lan->iface.nameserver[1],
				            _("Enter the Secondary DNS(name-) server to use here."), 4, lan);
    entry=g_object_get_data(G_OBJECT(lan->static_window), "nameserver2");
    g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_staticip), lan);
				      
    GtkWidget *separator = gtk_hseparator_new();        
    gtk_table_attach(GTK_TABLE(ctable), separator, 0, 3, 5, 6,
                      (GtkAttachOptions) GTK_FILL|(GtkAttachOptions) GTK_EXPAND, 
                      (GtkAttachOptions) GTK_FILL|(GtkAttachOptions) GTK_EXPAND, 0, 15);  //6, 7   

    GtkWidget *box;
    GtkWidget *button;
    box=gtk_hbox_new(TRUE,8);        
    gtk_table_attach(GTK_TABLE (ctable), box, 2, 3, 7, 8,
                      (GtkAttachOptions) GTK_FILL, 
                      (GtkAttachOptions) GTK_FILL, 0, 0);//7, 8,
        
    button=gtk_button_new_from_stock(GTK_STOCK_OK); 
    gtk_widget_set_size_request(button,90,35);
    gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(set_staticip), lan);//
    gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
    
    button=gtk_button_new_from_stock(GTK_STOCK_CANCEL);     
    gtk_widget_set_size_request(button,90, 35);
    gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
    gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
    gtk_widget_show_all(lan->static_window);

    return;
}

static gint get_first_char(gchar *s)
{
	gint i = 0;

    if (s == NULL)
    {
        return -1;
    }
	for (i=0; i<strlen(s); i++)
		if ((s[i] != ' ') && (s[i] != '\t') && (s[i] != '\n') && (s[i] != '\0')) return i;
	return -1;
}

static gint get_param_val(gchar* line, gchar* param, gchar* value)
{
    gint a = 0;
    gint b = 0;
    gint st = 0;
    gint sep = 0;
	
    st = get_first_char(line);
    if (line[st] == '#') return -1; // mark comment 
    for (sep=st; sep<strlen(line); sep++)
        if (line[sep]==' ') break;
    for (a=sep; a<strlen(line); a++)
        if ((line[a]!=' ') && (line[a]!='\t')) break;
    for (b=a+1; b<strlen(line); b++)
        if ((line[b]=='\n') || (line[b]=='\0')) break;
    param = strncpy(param,&line[st],sep-st);
    param[sep-st] = '\0';

    if ((b-a) > 0) value = strncpy(value,&line[a],b-a);	
    value[b-a]='\0';
    return 0;
}

static void read_interface_info(Iface_t *iface)
{
    gchar *filename;
    FILE *fd;
    char buffer[256] = {0};
    gchar paramval[256];
    gchar ifname[256];
    gchar *ret;
    gint index = 0;

    filename = g_strdup_printf("%sif_%s", NET_CONFIG_FOLDER, iface->name);    
    if (!access(filename, 4))
    {
        printf("Access file success:%s\n", filename);
        fd = fopen(filename, "r");
        if (fd)
        {
            do
            {
                ret = fgets(buffer, 255, fd);
                //printf("get from file: %s\n", buffer);
                if (get_param_val(buffer, paramval, ifname) == -1) 
                {
                    printf("call %s failed!\n");
                    memset(buffer, 0, 256);
                    continue;  
                }
                if (!strcmp("iface", paramval))
                {
                    if (!strcmp(paramval, iface->name))
                    {
                        printf("Wrong config file.\n");
                        fclose(fd);
                        return;
                    }
                }
                else if (!strcmp("address", paramval))
                {
                    strcpy(iface->address, g_strstrip(ifname));
                }
                else if (!strcmp("netmask", paramval))
                {
                    strcpy(iface->netmask,g_strstrip(ifname));
                }
                else if(!strcmp("gateway", paramval))
                {
                    strcpy(iface->gateway, g_strstrip(ifname));
                }
                else if(!strcmp("nameserver", paramval))
                {
                    iface->nameserver[index] = g_strdup(ifname);
                    //printf("****get nameserver %d: %s\n", index, iface->nameserver[index]);
                    index++;
                }
                memset(buffer, 0, 256);
            }while(ret!=NULL);
            fclose(fd);
        }
    }
}

static void wirte_interface_info(Iface_t *iface)
{
    FILE *fd = NULL;
    gchar *ret = NULL;
    gchar *filename = NULL;
    gchar ifname[256] = {0};
    gchar buffer[256] = {0};
    gchar paramval[256] = {0};

    // check param
    if (NULL == iface)
    {
        fprintf(stderr, "input param invalid in %s\n", __func__);
        return;
    }

    filename = g_strdup_printf("%sif_%s", NET_CONFIG_FOLDER, iface->name);    
    remove(filename);
    fd = fopen(filename, "w");
    if (fd)
    {
        if (iface->name)
        {
            fprintf(fd, "iface %s\n", iface->name);
        }      
        if (!iface->isdhcp)
        {
            fprintf(fd, "addrtype static\n");
        }
        else
        {
            fprintf(fd, "addrtype dhcp\n");
        }        
        if (iface->address)
        {
            fprintf(fd, "address %s\n", iface->address);
        }
        if (iface->netmask)
        {
            fprintf(fd, "netmask %s\n", iface->netmask);
        }
        if (iface->gateway)
        {
            fprintf(fd, "gateway %s\n", iface->gateway);
        }
        if (iface->nameserver[0])
        {
            fprintf(fd, "nameserver %s\n", iface->nameserver[0]);
        }
        else
        {
            fprintf(fd, "nameserver \n");
        }
        if (iface->nameserver[1])
        {
            fprintf(fd, "nameserver %s\n", iface->nameserver[1]);
        }
    }
    fclose(fd);
}

static void show_staticip_dlg(NetWorkLan *lan)
{
    // check param
    if (NULL == lan)
    {
        fprintf(stderr, "input param invalid in %s\n", __func__);
        return;
    }
    
    create_network_widgets(lan);
}

static gint lan_quit(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    GdkEventKey *key;
    
    key = (GdkEventKey *)event;
    if (key->keyval != GDK_Escape)
    {
        return FALSE;
    }
    
    gtk_exit(0);
    return TRUE;
}
void show_lan(NetWorkLan *lan)
{
    gint result;
    GtkWidget *msgdlg;

    // check param
    if (NULL == lan)
    {
        fprintf(stderr, "input param invalid in %s\n", __func__);
        return;
    }
    
    // create a message dialog
    msgdlg = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
        _("Please select connect mode, Use dhcp get ip automatically or set static ip manually."));
    g_signal_connect(G_OBJECT(msgdlg), "delete-event",
                	G_CALLBACK(gtk_exit), NULL);

    gtk_dialog_add_buttons(GTK_DIALOG(msgdlg), _("DHCP"), RESPONSE_DHCP,
                                   _("Static IP"), RESPONSE_STATIC, NULL);
    gtk_widget_add_events(GTK_WIDGET(msgdlg), GDK_KEY_PRESS_MASK);
    gtk_signal_connect(GTK_OBJECT(msgdlg), "key-press-event",GTK_SIGNAL_FUNC(lan_quit),NULL);

    result = gtk_dialog_run(GTK_DIALOG(msgdlg));
    g_object_set (G_OBJECT (msgdlg), "text", "Connecting Network.\n                                                           ", NULL);
    //gtk_widget_destroy(msgdlg);
    switch (result)
    {
    case RESPONSE_DHCP:
        memset(&(lan->iface), 0, sizeof(Iface_t));
        strcpy(lan->iface.name, "eth0");
        read_interface_info(&(lan->iface));
        lan->iface.isdhcp = TRUE;
        wirte_interface_info(&(lan->iface));
        lan_connect(lan);
        break;
        
    case RESPONSE_STATIC:
        gtk_widget_destroy(msgdlg);
        memset(&(lan->iface), 0, sizeof(Iface_t));
        strcpy(lan->iface.name, "eth0");
        printf("---begain read interface info----\n");
        read_interface_info(&(lan->iface));
        lan->iface.isdhcp = FALSE;

        if ((lan->iface.nameserver[0] == NULL) && (lan->iface.nameserver[1] == NULL))
        {
            gchar *nameserverfile = NULL;
            nameserverfile = g_strdup("/etc/resolv.conf");
            get_name_server(nameserverfile, lan);
            if (!lan->iface.nameserver[0]) 
                lan->iface.nameserver[0] = g_strdup("");
            if (!lan->iface.nameserver[1]) 
                lan->iface.nameserver[1] = g_strdup("");
        }
        printf("~~%s ,%s \n" ,lan->iface.nameserver[0] ,lan->iface.nameserver[1]);
        show_staticip_dlg(lan);
        break;
        
    default:
        printf("select default normal load mode");
        break;
    }
    
    return;
}

